package com.woniuxy.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.ArrayList;
import java.util.Collection;


/**
 * @author linke
 * @version 1.0
 * @className: MyRealm
 * @description: 自定义认证 授权
 * @date 2021/11/19 21:38
 */
public class MyRealm extends AuthorizingRealm {

    /**
     * 返回授权信息
     * 获取授权信息的方法
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("================doGetAuthorizationInfo");
        //去数据库的权限表查询当前用户的所有权限,获取当前用户
        Object primaryPrincipal = principals.getPrimaryPrincipal();
        System.out.println("================查询指定用户的所有权限:"+primaryPrincipal);
        Collection<String> permissions=new ArrayList<String>();
        //模拟从数据库中查询到的权限
        permissions.add("user:select");
        permissions.add("user:update");
        permissions.add("user:insert");
        SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
        //将查询出来的权限信息 添加进 授权
        authorizationInfo.addStringPermissions(permissions);
        //返回 授权信息
        return authorizationInfo;
    }

    /**
     *  返回认证信息
     * @param token 前端传递的数据
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        //AuthenticationToken:参数就是调用login()时传过来的token
        //获取用户登录时输入的用户名
        Object principal=token.getPrincipal();
        //去数据库根据用户名获取当前用户的完整对象，
        //数据库查询没有当前用户,dao返回null
        if(!"a".equals(principal)) {
            //模拟数据只要一条数据，登录用户名不是a，就返回null
            //Shiro框架，认证信息返回null,抛出UnknownAccountException
            return null;
        }
        //用户名存在，在凭证中保存要比对的密码
        //用户注册已经使用加密算法+盐+迭代次数，将加密的密码存入数据库
        Object credentials="567aedb9dc36acc7fdc8f08c7a51133a";
        //盐值 可以每个人都不同 迭代次数不能随机
        String strsalt="x";
        ByteSource salt= ByteSource.Util.bytes(strsalt);
        //Object principal, 身份信息，用户名或者用户对象
        //Object credentials, 凭证,比较验证的真实密码
        //ByteSource credentialsSalt ,盐值
        //String realmName,当前realm的名字
        AuthenticationInfo authenticationInfo=
                new SimpleAuthenticationInfo(principal, credentials,salt, this.getName());
        //框架底层将AuthenticationToken和AuthenticationInfo的密码进行比较，相对，登录成功；
        //不等IncorrectCredentialsException
        return authenticationInfo;
    }
}
